"""
智能环境监测模拟系统
[程序简介]
基于Tkinter GUI开发的环境数据监测模拟系统，支持多用户并行操作。可模拟生成温度、湿度和CO2数据，
实时展示监测状态，记录带颜色区分的操作日志，并提供数据导出功能

[主要功能]
1. 用户控制：10个独立用户的启动/中止监测控制
2. 实时展示：表格形式显示最新环境数据（温度、湿度、CO2）
3. 智能日志：彩色区分操作类型（绿色启动/红色中止/蓝色数据更新）
4. 数据管理：自动保存监测记录，支持导出Excel格式
5. 智能排序：实时数据栏按用户ID顺序排列，中止后自动清除对应数据

[使用方法]
1. 界面操作：
   - 点击「启动」按钮：开始对应用户的实时监测
   - 点击「中止」按钮：停止监测并清除对应数据行
   - 点击「导出Excel」：将所有监测数据导出到当前目录

2. 运行效果：
   - 启动用户：实时数据栏显示对应行，日志显示绿色记录
   - 数据更新：每10秒自动刷新，日志显示蓝色记录
   - 中止用户：立即清除对应数据行，日志显示红色记录
   - 导出数据：生成environment_data.xlsx文件，包含完整历史记录

[注意事项]
1. 数据更新间隔固定为10秒
2. 导出文件会覆盖同名现有文件
"""

import tkinter as tk
from tkinter import ttk, messagebox

# import random
import pandas as pd
import threading
from sys import argv
from datetime import datetime
from generator import get_single_data

translators = {
    "家庭": "family",
    "实验室": "lab",
    "温室": "greenhouse",
    "冬季": "winter",
    "夏季": "summer",
}


class EnvironmentMonitor:
    def __init__(self, root):
        # 初始化
        self.root = root
        self.root.title("智能环境监测模拟系统")

        # 初始化数据结构
        self.users = {
            i: {"running": False, "data": [], "sc": None, "se": None}
            for i in range(1, 11)
        }
        self.logs = []
        self.lock = threading.Lock()

        # 创建界面
        self.create_widgets()
        self.create_data_display()
        self.create_log_display()

    def create_widgets(self):
        # 控制面板
        control_frame = ttk.LabelFrame(self.root, text="用户控制")
        control_frame.grid(row=0, column=0, padx=10, pady=5, sticky="n")

        # 用户
        for user_id in range(1, 11):
            # 创建一个框架来容纳每个用户的控件
            user_frame = ttk.Frame(control_frame)
            user_frame.grid(
                row=(user_id - 1) // 2,
                column=(user_id - 1) % 2,
                padx=10,
                pady=5,
                sticky="w",
            )

            # 用户标签
            ttk.Label(user_frame, text=f"用户 {user_id}", width=7).grid(
                row=0, column=0, padx=5
            )

            # 环境下拉菜单
            scene_label = ttk.Label(user_frame, text="环境:")
            scene_label.grid(row=0, column=1, padx=5)
            scene_combobox = ttk.Combobox(
                user_frame, values=["家庭", "实验室", "温室"], width=10
            )
            scene_combobox.grid(row=0, column=2, padx=5)
            scene_combobox.set("家庭")  # 设置默认值
            self.users[user_id]["sc"] = scene_combobox

            # 季节下拉菜单
            season_label = ttk.Label(user_frame, text="季节:")
            season_label.grid(row=0, column=3, padx=5)
            season_combobox = ttk.Combobox(
                user_frame, values=["冬季", "夏季"], width=10
            )
            season_combobox.grid(row=0, column=4, padx=5)
            season_combobox.set("冬季")  # 设置默认值
            self.users[user_id]["se"] = season_combobox

            # 启动按钮
            ttk.Button(
                user_frame,
                text="启动",
                command=lambda uid=user_id: self.start_monitoring(uid),
            ).grid(row=0, column=5, padx=2)

            # 中止按钮
            ttk.Button(
                user_frame,
                text="中止",
                command=lambda uid=user_id: self.stop_monitoring(uid),
            ).grid(row=0, column=6, padx=2)

        # 设置父容器的列配置，使中间列占据剩余空间
        # control_frame.grid_configure(8, weight=1)  # 根据您的布局设置列权重

        # 导出按钮
        ttk.Button(control_frame, text="导出Excel", command=self.export_data).grid(
            row=5, column=0, columnspan=3, padx=10, pady=5, sticky="nsew"
        )

    def create_data_display(self):
        # 数据显示区域
        data_frame = ttk.LabelFrame(self.root, text="实时数据")
        data_frame.grid(row=1, column=0, padx=10, pady=5, sticky="n")

        columns = {
            "user_id": "用户ID",
            "temperature": "温度",
            "humidity": "湿度",
            "fresh_air": "新风量",
            "ozone": "臭氧含量",
            "nitro_dio": "二氧化氮",
            "methanal": "甲醛",
            "pm2_5": "细颗粒物（PM2.5）",
            "carb_momo": "一氧化碳",
            "bacteria": "细菌总数",
            "radon": "氡",
            "pah": "PAH",
        }
        self.tree = ttk.Treeview(
            data_frame, columns=columns, show="headings", height=15
        )

        for col in columns:
            self.tree.heading(col, text=col, anchor="center")
            self.tree.column(col, width=100, anchor="center")

        self.tree.pack()

    def create_log_display(self):
        # 日志显示区域
        log_frame = ttk.LabelFrame(self.root, text="操作日志")
        log_frame.grid(row=2, column=0, columnspan=2, padx=10, pady=5, sticky="ew")

        self.log_text = tk.Text(log_frame, height=8, state="disabled")
        scrollbar = ttk.Scrollbar(log_frame, command=self.log_text.yview)
        self.log_text.configure(yscrollcommand=scrollbar.set)

        scrollbar.pack(side="right", fill="y")
        self.log_text.pack(fill="both", expand=True)

    def update_data_display(self):
        """更新表格显示（按用户序号排序）"""
        # 清空现有数据
        for item in self.tree.get_children():
            self.tree.delete(item)

        # 按用户ID顺序插入数据
        for user_id in sorted(self.users.keys()):
            if self.users[user_id]["running"] and self.users[user_id]["data"]:
                latest_data = self.users[user_id]["data"][-1]
                values = list(latest_data.values())[1:]
                self.tree.insert("", "end", values=values)

        # 自动滚动到最后
        if self.tree.get_children():
            self.tree.see(self.tree.get_children()[-1])

    def log_operation(self, user_id, action):
        """记录操作日志"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"{timestamp} - 用户 {user_id} {action}\n"

        color_map = {"启动监测": "green", "中止监测": "red", "数据更新": "blue"}

        with self.lock:
            self.logs.append(log_entry)

        self.log_text.config(state="normal")
        self.log_text.insert("end", log_entry)
        self.log_text.tag_add(action, "end-2l linestart", "end-1c")
        self.log_text.tag_config(action, foreground=color_map[action])
        self.log_text.config(state="disabled")
        self.log_text.see("end")

    def start_monitoring(self, user_id):
        """启动监测"""
        if not self.users[user_id]["running"]:
            self.users[user_id]["running"] = True
            self.log_operation(user_id, "启动监测")
            threading.Thread(
                target=self.monitor_loop, args=(user_id,), daemon=True
            ).start()

    def stop_monitoring(self, user_id):
        """停止监测"""
        if self.users[user_id]["running"]:
            self.users[user_id]["running"] = False
            self.log_operation(user_id, "中止监测")
            self.update_data_display()  # 立即更新界面

    def monitor_loop(self, user_id):
        """监测循环"""
        while self.users[user_id]["running"]:
            # data = self.generate_valid_data()
            user_data = self.users[user_id]
            # print(user_id)
            data = get_single_data(
                translators[user_data["sc"].get()],
                translators[user_data["se"].get()],
                user_id,
            )
            print(data)

            with self.lock:
                self.users[user_id]["data"].append(data)

            self.root.after(0, self.update_data_display)
            self.log_operation(user_id, "数据更新")
            threading.Event().wait(0.1)  # 每10s更新一次

    def export_data(self):
        """导出数据到Excel"""
        try:
            data = []
            for user_id in self.users:
                for record in self.users[user_id]["data"]:
                    data.append({"用户": user_id} | record)

            df = pd.DataFrame(data)
            df.to_excel("environment_data.xlsx", index=False)
            messagebox.showinfo("导出成功", "数据已成功导出到 environment_data.xlsx")
        except Exception as e:
            messagebox.showerror("导出错误", f"导出数据时发生错误: {str(e)}")


if __name__ == "__main__":
    root = tk.Tk()
    app = EnvironmentMonitor(root)
    root.mainloop()
